Developer Guide
Overview
IO River Unified Edge Compute allows developers to write edge logic once using IO River APIs and deploy it automatically across multiple edge platforms such as:
- Cloudflare Workers
- CloudFront Functions and Lambda@Edge
- Fastly Compute
The IO River runtime abstracts differences between these providers, so your code is platform-agnostic and portable.
Developers implement two optional lifecycle handlers:
onRequest(request)– Executed when a request arrives at the edge.onResponse(request, response)– Executed before the response is sent to the client.
Execution Model
onRequest(request)
Triggered when the incoming HTTP request reaches the edge.
Use it to:
- Modify headers
- Rewrite URLs
- Route to different backends
- Call external services
- Generate custom responses
Return value:
- Can return either
IORRequestorIORResponse - Can return the result of
ior_fetch()
onResponse(request, response)
Triggered after a response is generated but before it is returned to the end user.
Use it to:
- Modify response headers
- Adjust status codes
- Rewrite body
- Add security headers
Return value:
- Must return an
IORResponse
Core APIs
IORRequest
Represents the incoming HTTP request.
Properties
| Property | Type | Description |
|---|---|---|
request.url | string | Full request URL |
request.method | string | HTTP method (GET, POST, etc.) |
request.headers | Headers | Request headers object |
Accessing Body
Use either request.json() or request.text() to retrieve the request body.
Note that these methods consume the body. If you only need to read the body and preserve it, you should clone the request and consume it from the cloned instance.
Accessing Headers
request.headers behaves like the standard Web Fetch API Headers.
Get a Header
let userAgent = request.headers.get("User-Agent");
Set a Header
request.headers.set("x-custom-header", "value");
Delete a Header
request.headers.delete("Cookie");
Check if Header Exists
request.headers.has("Authorization");
IORResponse
Represents an HTTP response.
Returned either from:
ior_fetch()- Manually constructed response in
onRequestoronResponse - Modified inside
onResponse
Properties
| Property | Type | Description |
|---|---|---|
response.status | number | HTTP status code |
response.headers | Headers | Response headers |
Accessing Body
Use either response.json() or response.text() to retrieve the response body.
Note that these methods consume the body. If you only need to read the body and preserve it, you should clone the request and consume it from the cloned instance. This is not supported for CloudFront.
Modifying Response Headers
Set a Header
response.headers.set("x-powered-by", "IO River");
Get a Header
let contentType = response.headers.get("Content-Type");
Delete a Header
response.headers.delete("Server");
Making Outbound Requests – ior_fetch()
ior_fetch() is the platform-agnostic fetch function.
It works similarly to the standard Fetch API but is adapted internally per edge provider.
Syntax
let response = await ior_fetch(url, {
method: "POST",
headers: headers,
body: body,
});
Parameters
| Parameter | Description |
|---|---|
url | String or URL object |
method | HTTP method |
headers | Headers object |
body | Optional request body |
Returns:
Promise<IORResponse>
Examples
Example: Proxy Request to Another Host
async function onRequest(request) {
var url = new URL(request.url);
var headers = new Headers(request.headers);
url.hostname = "test.example.com";
headers.set("Authorization", "Basic abcd1234");
let response = await ior_fetch(url, {
headers: headers,
method: request.method,
});
return response;
}
What This Does
- Rewrites hostname
- Adds Authorization header
- Forwards original HTTP method
- Returns origin response
Example: Modify Response Before Sending to the End-User
async function onResponse(request, response) {
response.headers.set("foo", "bar");
return response;
}
Example: Working With URL
You can use standard Web API URL:
var url = new URL(request.url);
url.pathname = "/new-path";
url.searchParams.set("debug", "true");
Example: Creating a Custom Response
You may return a new response directly:
return new IORResponse("Blocked", {
status: 403,
headers: {
"content-type": "text/plain",
},
});
Best Practices
1. Clone Headers Before Modifying
Always create a new Headers object if forwarding:
var headers = new Headers(request.headers);
Avoid mutating the original unless necessary.
2. Preserve Method and Body for Proxying
let response = await ior_fetch(url, {
method: request.method,
headers: headers,
body: request.text(),
});
3. Avoid Blocking Operations
All handlers must be async and non-blocking.
Error Handling
Use try/catch inside handlers:
async function onRequest(request) {
try {
return await ior_fetch(request.url);
} catch (e) {
return new IORResponse("Upstream Error", { status: 502 });
}
}
Lifecycle Summary
Incoming Request
↓
onRequest()
↓
(optional ior_fetch)
↓
Origin Response
↓
onResponse()
↓
End User
Conclusion
IO River Unified Edge Compute enables:
- Write once, deploy everywhere
- Standard Web API-like interface
- Full request and response control
- Platform abstraction across major edge providers